package smartclass.shape;

import java.util.ArrayList;
import java.util.HashMap;

import smartclass.analysisData.AnalysisPoint;
import smartclass.data.FinalValues;
import smartclass.slidingmenu.example.LeftAndRightActivity;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.Log;

import com.samsung.android.sdk.pen.document.SpenObjectBase;
import com.samsung.android.sdk.pen.document.SpenObjectContainer;
import com.samsung.android.sdk.pen.document.SpenObjectStroke;
import com.samsung.android.sdk.pen.document.SpenObjectTextBox;
import com.samsung.android.sdk.pen.document.SpenPageDoc;
import com.samsung.android.sdk.pen.engine.SpenSurfaceView;
import com.samsung.android.sdk.pen.settingui.SpenSettingPenLayout;

public class BasicShape {
	SpenSurfaceView mSpenSurfaceView;
	SpenSettingPenLayout mPenSettingView;
	SpenPageDoc mSpenPageDoc;
	PointF rootPoint;

	public BasicShape(SpenSurfaceView mSpenSurfaceView,
			SpenSettingPenLayout mPenSettingView, SpenPageDoc mSpenPageDoc) {
		// TODO Auto-generated constructor stub
		this.mPenSettingView = mPenSettingView;
		this.mSpenSurfaceView = mSpenSurfaceView;
		this.mSpenPageDoc = mSpenPageDoc;
		rootPoint = new PointF(0, 0);
	}

	public void drawCircle(PointF startPoint, PointF endPoint) {
		PointF p1 = new PointF();
		PointF p2 = new PointF();
		p1 = getRealPoint(startPoint);
		p2 = getRealPoint(endPoint);
		drawCirleReal(p1, p2);
	}

	public void drawElip(PointF startPoint, PointF endPoint) {
		PointF p1 = new PointF();
		PointF p2 = new PointF();
		p1 = getRealPoint(startPoint);
		p2 = getRealPoint(endPoint);
		drawElipReal(p1, p2);

	}

	public void drawRect(PointF startPoint, PointF endPointF) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPointF);
		drawRectReal(p1, p2);
	}

	public void drawLine(PointF startPoint, PointF endPoint) {
		PointF p1 = new PointF();
		PointF p2 = new PointF();
		p1 = getRealPoint(startPoint);
		p2 = getRealPoint(endPoint);
		drawLineReal(p1, p2);

	}

	public void drawTriangle(PointF startPoint, PointF endPoint) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawTriangleReal(p1, p2);
	}

	public void drawRigthTriangle(PointF startPoint, PointF endPoint) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawRigthTriangleReal(p1, p2);
	}

	public void drawParabol(PointF startPoint, PointF endPoint) {

		PointF p1 = new PointF();
		PointF p2 = new PointF();
		p1 = getRealPoint(startPoint);
		p2 = getRealPoint(endPoint);
		drawParabolReal(p1, p2);

	}

	public void drawParallelogram(PointF startPoint, PointF endPoint) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawParallelogramReal(p1, p2);

	}

	public void drawRhombus(PointF startPoint, PointF endPoint) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawRhombusReal(p1, p2);
	}

	public void drawIsoscelesTrapezoid(PointF startPoint, PointF endPoint) {

		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawIsoscelesTrapezoidReal(p1, p2);
	}

	public void drawTrapezoidalSquare(PointF startPoint, PointF endPoint) {
		PointF p1 = getRealPoint(startPoint);
		PointF p2 = getRealPoint(endPoint);
		drawTrapezoidalSquareReal(p1, p2);
	}

	public void drawDevideDimension(PointF endPoint) {

		PointF realPoint = new PointF();
		realPoint.x = (int) (getRealPoint(endPoint).x / 40) * 40;
		realPoint.y = (int) (getRealPoint(endPoint).y / 40) * 40;
		int x = mSpenSurfaceView.getCanvasWidth();
		// int y = mSpenSurfaceView.getCanvasHeight();
		PointF p1 = realPoint;
		PointF p2 = new PointF(x, realPoint.y);
		rootPoint = realPoint;
		int pointSize = x - (int) realPoint.x + (int) realPoint.y;

		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		int delta = 1;

		float x0 = p1.x - delta;

		for (int i = x - (int) realPoint.x; i >= 0; i--) {
			points[i] = new PointF();
			x0 = x0 + delta;
			points[i].x = x0;
			points[i].y = realPoint.y;
			pressures[i] = 1;
			timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
		}

		p2 = new PointF(realPoint.x, 0);

		if (p1.y > p2.y)
			delta = -1;
		float y0 = p1.y - delta;
		for (int i = x - (int) p1.x; i < pointSize; i++) {
			points[i] = new PointF();
			y0 = y0 + delta;
			points[i].x = p1.x;
			points[i].y = y0;
			pressures[i] = 1;
			timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
		}

		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.LINE + ":"
				+ endPoint.x + ";" + endPoint.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();

	}

	public void drawLevelDimension(PointF endPoint) {
		PointF realPoint = new PointF();
		realPoint.x = (int) (getRealPoint(endPoint).x / 40) * 40;
		realPoint.y = (int) (getRealPoint(endPoint).y / 40) * 40;

		SpenObjectTextBox textObj;
		int i = (int) ((mSpenSurfaceView.getCanvasWidth() - realPoint.x) / 40);
		int j = (int) (realPoint.y) / 40;
		if (i * 40 == mSpenSurfaceView.getCanvasWidth() + (int) realPoint.x)
			i++;
		if (j * 40 == (int) realPoint.y)
			j++;
		int x = (int) realPoint.x;
		int y = (int) realPoint.y;
		int k;
		PointF p1 = new PointF();

		int delta = 1;
		int pointSize = 12;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		for (k = 0; k < i; k++) {
			textObj = new SpenObjectTextBox();

			RectF rect = new RectF(x - 10, y, x - 10, y);
			rect.right += 350;
			rect.bottom += 50;
			textObj.setRect(rect, false);
			textObj.setFontSize(18);
			textObj.setReadOnlyEnabled(true);
			textObj.setText(k + "");
			mSpenPageDoc.appendObject(textObj);
			mSpenSurfaceView.update();
			if (k != 0) {

				p1 = new PointF(x, y - 6);

				float y0 = p1.y - delta;
				for (int h = 0; h < pointSize; h++) {
					points[h] = new PointF();
					y0 = y0 + delta;
					points[h].x = p1.x;
					points[h].y = y0;
					pressures[h] = 1;
					timestamps[h] = (int) android.os.SystemClock.uptimeMillis();
				}

				SpenObjectStroke strokeObj = new SpenObjectStroke(
						mPenSettingView.getInfo().name, points, pressures,
						timestamps);
				strokeObj.setPenSize(mPenSettingView.getInfo().size);
				strokeObj.setColor(mPenSettingView.getInfo().color);
				mSpenPageDoc.appendObject(strokeObj);
				mSpenSurfaceView.update();
			}
			x += 40;
		}
		x = (int) realPoint.x;
		y = (int) realPoint.y;
		points = new PointF[pointSize];
		for (k = 0; k < j; k++) {
			textObj = new SpenObjectTextBox();
			y -= 40;
			p1 = new PointF(x - 6, y);

			float x0 = p1.x - delta;
			for (int l = 0; l < pointSize; l++) {
				points[l] = new PointF();
				x0 = x0 + delta;
				points[l].x = x0;
				points[l].y = y;
				pressures[l] = 1;
				timestamps[l] = (int) android.os.SystemClock.uptimeMillis();

			}
			SpenObjectStroke strokeObj = new SpenObjectStroke(
					mPenSettingView.getInfo().name, points, pressures,
					timestamps);
			strokeObj.setPenSize(mPenSettingView.getInfo().size);
			strokeObj.setColor(mPenSettingView.getInfo().color);
			mSpenPageDoc.appendObject(strokeObj);
			mSpenSurfaceView.update();

			RectF rect = new RectF(x - 35, y - 20, x - 35, y - 20);
			rect.right += 350;
			rect.bottom += 50;
			textObj.setRect(rect, false);
			textObj.setFontSize(18);
			textObj.setText(k + 1 + "");
			mSpenPageDoc.appendObject(textObj);
			mSpenSurfaceView.update();
		}

	}

	public void drawDevideDimension_v2(PointF endPoint) {

		PointF realPoint = new PointF();
		realPoint.x = (int) (getRealPoint(endPoint).x / 40) * 40;
		realPoint.y = (int) (getRealPoint(endPoint).y / 40) * 40;
		int x = mSpenSurfaceView.getCanvasWidth();
		int y = mSpenSurfaceView.getCanvasHeight();
		rootPoint = realPoint;
		drawLineReal(new PointF(0, realPoint.y), new PointF(x, realPoint.y));
		drawLineReal(new PointF(realPoint.x, 0), new PointF(realPoint.x, y));
	}

	public void drawLevelDimension_v2(PointF endPoint) {

		PointF realPoint = new PointF();
		realPoint.x = (int) (getRealPoint(endPoint).x / 40) * 40;
		realPoint.y = (int) (getRealPoint(endPoint).y / 40) * 40;

		SpenObjectTextBox textObj;
		int i = (int) ((mSpenSurfaceView.getCanvasWidth()) / 40);
		int j = (int) (mSpenSurfaceView.getCanvasHeight()) / 40;
		if (i * 40 == mSpenSurfaceView.getCanvasWidth())
			i++;
		if (j * 40 == mSpenSurfaceView.getCanvasHeight())
			j++;
		int x1 = (int) realPoint.x;
		int x = 0;
		int y = (int) realPoint.y;
		int y1 = mSpenSurfaceView.getCanvasHeight();
		int k;
		PointF p1 = new PointF();

		int delta = 1;
		int pointSize = 12;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		for (k = 0; k < i; k++) {
			textObj = new SpenObjectTextBox();
			if (k - x1 / 40 != 0) {
				RectF rect = new RectF(x - 10, y, x - 10, y);
				rect.right += 50;
				rect.bottom += 50;
				textObj.setRect(rect, false);
				textObj.setFontSize(18);
				textObj.setSelectable(false);
				textObj.setText(k - (x1 / 40) + "");
				Log.e("X1", x1 / 40 + " ");
				mSpenPageDoc.appendObject(textObj);
				mSpenSurfaceView.update();

				p1 = new PointF(x, y - 6);

				float y0 = p1.y - delta;
				for (int h = 0; h < pointSize; h++) {
					points[h] = new PointF();
					y0 = y0 + delta;
					points[h].x = p1.x;
					points[h].y = y0;
					pressures[h] = 1;
					timestamps[h] = (int) android.os.SystemClock.uptimeMillis();
				}

				SpenObjectStroke strokeObj = new SpenObjectStroke(
						mPenSettingView.getInfo().name, points, pressures,
						timestamps);
				strokeObj.setSelectable(false);
				strokeObj.setPenSize(mPenSettingView.getInfo().size);
				strokeObj.setColor(mPenSettingView.getInfo().color);
				ArrayList<SpenObjectBase> tmp = new ArrayList<SpenObjectBase>();
				tmp.add(strokeObj);
				SpenObjectContainer mSpenContainer = new SpenObjectContainer(
						tmp);
				mSpenContainer.setSelectable(false);
				mSpenPageDoc.appendObject(mSpenContainer);
				mSpenSurfaceView.update();
			}
			x += 40;
		}
		x = (int) realPoint.x;

		points = new PointF[pointSize];
		for (k = 0; k < j; k++) {
			textObj = new SpenObjectTextBox();

			p1 = new PointF(x - 6, y1);

			float x0 = p1.x - delta;
			for (int l = 0; l < pointSize; l++) {
				points[l] = new PointF();
				x0 = x0 + delta;
				points[l].x = x0;
				points[l].y = y1;
				pressures[l] = 1;
				timestamps[l] = (int) android.os.SystemClock.uptimeMillis();

			}
			SpenObjectStroke strokeObj = new SpenObjectStroke(
					mPenSettingView.getInfo().name, points, pressures,
					timestamps);
			strokeObj.setSelectable(false);
			strokeObj.setPenSize(mPenSettingView.getInfo().size);
			strokeObj.setColor(mPenSettingView.getInfo().color);
			mSpenPageDoc.appendObject(strokeObj);
			mSpenSurfaceView.update();
			RectF rect = null;
			if (k - (mSpenSurfaceView.getCanvasHeight() - y) / 40 == 0) {
				rect = new RectF(x - 35, y1 - 30, x - 35, y1 - 30);
			} else {
				rect = new RectF(x - 35, y1 - 20, x - 35, y1 - 20);
			}
			rect.right += 50;
			rect.bottom += 50;
			textObj.setRect(rect, false);
			textObj.setFontSize(18);
			textObj.setSelectable(false);
			textObj.setReadOnlyEnabled(true);
			textObj.setText(k - (mSpenSurfaceView.getCanvasHeight() - y) / 40
					+ "");
			mSpenPageDoc.appendObject(textObj);
			mSpenSurfaceView.update();
			y1 -= 40;
		}

	}

	public void drawPointOnDimension(PointF inputPoint) {

		PointF p1 = new PointF(inputPoint.x * 40 + rootPoint.x, rootPoint.y
				- inputPoint.y * 40);

		drawLineReal(p1, rootPoint);

	}

	public void drawElipReal(PointF p1, PointF p2) {
		int pointSize = 361;

		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		for (int i = 0; i < pointSize; i++) {
			points[i] = new PointF();
			points[i].x = (float) (p1.x + Math.abs(p1.x - p2.x)
					* (Math.sin(i * 2 * Math.PI / 180)));
			points[i].y = (float) (p1.y + Math.abs(p1.y - p2.y)
					* (Math.cos(i * 2 * Math.PI / 180)));

			pressures[i] = 1;
			timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
		}
		Log.e("Size", points.length + "");
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Eip: Tam va diem cuoi nhac but.
		 */
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.ELIP + ":"
				+ p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawCirleReal(PointF p1, PointF p2) {
		float r = (float) Math.sqrt((Double) (Math.pow(p1.x - p2.x, 2) + Math
				.pow(p1.y - p2.y, 2)));
		Log.e("R Template", r + "");
		int pointSize = 361;

		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		for (int i = 0; i < pointSize; i++) {
			points[i] = new PointF();
			points[i].x = (float) (p1.x + r * (Math.sin(i * 2 * Math.PI / 180)));
			points[i].y = (float) (p1.y + r * (Math.cos(i * 2 * Math.PI / 180)));
			pressures[i] = 1;
			timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
		}
		Log.e("SIze", points.length + "");
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Circle : Toa do tam + diem tren cung ben phai cua hinh
		 * vuong ngoai tiep.
		 */
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.CIRCLE + ":"
				+ p1.x + ";" + p1.y + ";" + (p1.x + r) + ";" + (p1.y - r));
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawRectReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(new PointF(p1.x, p1.y), new PointF(
				p2.x, p1.y));
		PointF[] points2 = getPointLine(new PointF(p2.x, p1.y), new PointF(
				p2.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(p2.x, p2.y), new PointF(
				p1.x, p2.y));
		PointF[] points4 = getPointLine(new PointF(p1.x, p2.y), new PointF(
				p1.x, p1.y));

		int pointSize = points1.length + points2.length + points3.length
				+ points4.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < points1.length
				+ points2.length + points3.length; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length + points2.length + points3.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points4[i
					- (points1.length + points2.length + points3.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Rect: Diem dau + diem cuoi
		 */
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.RECTANGLE
				+ ":" + p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();

	}

	public void drawLineReal(PointF p1, PointF p2) {

		int pointSize = (int) Math.abs(p1.x - p2.x) + 1;
		if (p1.x == p2.x)
			pointSize = (int) Math.abs(p2.y - p1.y) + 1;

		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		if (p1.x != p2.x) {
			int delta = 1;
			if (p1.x > p2.x)
				delta = -1;
			float x0 = p1.x - delta;

			for (int i = 0; i < pointSize; i++) {
				points[i] = new PointF();
				x0 = x0 + delta;
				points[i].x = x0;
				points[i].y = (x0 - p1.x) * (p2.y - p1.y) / (p2.x - p1.x)
						+ p1.y;
				pressures[i] = 1;
				timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
			}
		} else {
			int delta = 1;
			if (p1.y > p2.y)
				delta = -1;
			float y0 = p1.y - delta;

			for (int i = 0; i < pointSize; i++) {
				points[i] = new PointF();
				y0 = y0 + delta;
				points[i].x = p1.x;
				points[i].y = y0;
				pressures[i] = 1;
				timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
			}
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawTriangleReal(PointF p1, PointF p2) {

		PointF[] points1 = getPointLine(p2, p1);
		PointF[] points2 = getPointLine(p1, new PointF(2 * p1.x - p2.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(2 * p1.x - p2.x, p2.y), p2);
		int pointSize = points1.length + points2.length + points3.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.TRIANGLE
				+ ":" + p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawRigthTriangleReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(p1, p2);
		PointF[] points2 = getPointLine(p2, new PointF(p1.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(p1.x, p2.y), p1);
		int pointSize = points1.length + points2.length + points3.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		//
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		strokeObj.setExtraDataString(FinalValues.KEY,
				FinalValues.RIGHTSTRIANGLE + ":" + p1.x + ";" + p1.y + ";"
						+ p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();

	}

	public void drawParabolReal(PointF p1, PointF p2) {

		int pointSize = (int) (2 * (Math.abs(p1.x - p2.x)));
		if (pointSize == 0) {
			drawLineReal(p1, p2);
			System.out.println("Draw Line");
			return;
		}

		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];

		for (int i = 0; i < pointSize; i++) {
			points[i] = new PointF();
			points[i].x = i - pointSize / 2 + p1.x;
			points[i].y = (float) ((p2.y - p1.y) * Math.pow((i - pointSize / 2)
					/ (p2.x - p1.x), 2))
					+ p1.y;
			pressures[i] = 1;
			timestamps[i] = (int) android.os.SystemClock.uptimeMillis();
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.PARABOL + ":"
				+ p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();

	}

	public void drawParallelogramReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(new PointF(p1.x, p1.y), new PointF(
				(float) (2 * p1.x + p2.x) / 3, p2.y));
		PointF[] points2 = getPointLine(new PointF(
				(float) (2 * p1.x + p2.x) / 3, p2.y), new PointF(p2.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(p2.x, p2.y), new PointF(
				(float) (2 * p2.x + p1.x) / 3, p1.y));
		PointF[] points4 = getPointLine(new PointF(
				(float) (2 * p2.x + p1.x) / 3, p1.y), new PointF(p1.x, p1.y));

		int pointSize = points1.length + points2.length + points3.length
				+ points4.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < points1.length
				+ points2.length + points3.length; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length + points2.length + points3.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points4[i
					- (points1.length + points2.length + points3.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Parallel: Diem dau + diem cuoi
		 */
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.PARALLEL
				+ ":" + p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawRhombusReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(new PointF(p1.x, p1.y), new PointF(2
				* p1.x - p2.x, p2.y));
		PointF[] points2 = getPointLine(new PointF(2 * p1.x - p2.x, p2.y),
				new PointF(p1.x, 2 * p2.y - p1.y));
		PointF[] points3 = getPointLine(new PointF(p1.x, 2 * p2.y - p1.y),
				new PointF(p2.x, p2.y));
		PointF[] points4 = getPointLine(new PointF(p2.x, p2.y), new PointF(
				p1.x, p1.y));

		int pointSize = points1.length + points2.length + points3.length
				+ points4.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < points1.length
				+ points2.length + points3.length; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length + points2.length + points3.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points4[i
					- (points1.length + points2.length + points3.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Parallel: Diem dau + diem cuoi
		 */
		strokeObj.setExtraDataString(FinalValues.KEY, FinalValues.RHOMBUS + ":"
				+ p1.x + ";" + p1.y + ";" + p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawIsoscelesTrapezoidReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(new PointF(p1.x, p1.y), new PointF(
				(float) (4 * p1.x - p2.x) / 3, p2.y));
		PointF[] points2 = getPointLine(new PointF(
				(float) (4 * p1.x - p2.x) / 3, p2.y), new PointF(p2.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(p2.x, p2.y), new PointF(
				(float) (p1.x + 2 * p2.x) / 3, p1.y));
		PointF[] points4 = getPointLine(new PointF(
				(float) (p1.x + 2 * p2.x) / 3, p1.y), new PointF(p1.x, p1.y));

		int pointSize = points1.length + points2.length + points3.length
				+ points4.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < points1.length
				+ points2.length + points3.length; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length + points2.length + points3.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points4[i
					- (points1.length + points2.length + points3.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Parallel: Diem dau + diem cuoi
		 */
		strokeObj.setExtraDataString(FinalValues.KEY,
				FinalValues.ISOSCELES_TRAPEZOID + ":" + p1.x + ";" + p1.y + ";"
						+ p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();
	}

	public void drawTrapezoidalSquareReal(PointF p1, PointF p2) {
		PointF[] points1 = getPointLine(new PointF(p1.x, p1.y), new PointF(
				p1.x, p2.y));
		PointF[] points2 = getPointLine(new PointF(p1.x, p2.y), new PointF(
				p2.x, p2.y));
		PointF[] points3 = getPointLine(new PointF(p2.x, p2.y), new PointF(
				(float) (p1.x + p2.x) / 2, p1.y));
		PointF[] points4 = getPointLine(new PointF((float) (p1.x + p2.x) / 2,
				p1.y), new PointF(p1.x, p1.y));

		int pointSize = points1.length + points2.length + points3.length
				+ points4.length;
		PointF[] points = new PointF[pointSize];
		float[] pressures = new float[pointSize];
		int[] timestamps = new int[pointSize];
		int i;
		for (i = 0; i < points1.length; i++) {
			points[i] = new PointF();
			points[i] = points1[i];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length; i < points1.length + points2.length; i++) {
			points[i] = new PointF();
			points[i] = points2[i - points1.length];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());

		}
		for (i = points1.length + points2.length; i < points1.length
				+ points2.length + points3.length; i++) {
			points[i] = new PointF();
			points[i] = points3[i - (points1.length + points2.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		for (i = points1.length + points2.length + points3.length; i < pointSize; i++) {
			points[i] = new PointF();
			points[i] = points4[i
					- (points1.length + points2.length + points3.length)];
			pressures[i] = 1;
			timestamps[i] = (int) (android.os.SystemClock.uptimeMillis());
		}
		SpenObjectStroke strokeObj = new SpenObjectStroke(
				mPenSettingView.getInfo().name, points, pressures, timestamps);
		strokeObj.setPenSize(mPenSettingView.getInfo().size);
		strokeObj.setColor(mPenSettingView.getInfo().color);
		/*
		 * Form save Parallel: Diem dau + diem cuoi
		 */
		strokeObj.setExtraDataString(FinalValues.KEY,
				FinalValues.ISOSCELES_SQUARE + ":" + p1.x + ";" + p1.y + ";"
						+ p2.x + ";" + p2.y);
		mSpenPageDoc.appendObject(strokeObj);
		mSpenSurfaceView.update();

	}

	public void drawLineEnterPoint(PointF p1, PointF p2) {
		PointF p1OnSys = getPointOnSystemDimension(p1);
		PointF p2OnSys = getPointOnSystemDimension(p2);
		drawLineReal(p1OnSys, p2OnSys);
	}

	public void drawCircleEnterPoint(PointF p1, PointF p2) {
		PointF p1OnSys = getPointOnSystemDimension(p1);
		PointF p2OnSys = getPointOnSystemDimension(p2);
		drawCirleReal(p1OnSys, p2OnSys);
	}

	public void drawElipEnterPoint(PointF p1, PointF p2) {
		PointF p1OnSys = getPointOnSystemDimension(p1);
		PointF p2OnSys = getPointOnSystemDimension(p2);
		drawElipReal(p1OnSys, p2OnSys);
	}

	public void drawParabolEnterPoint(PointF p1, PointF p2) {
		PointF p1OnSys = getPointOnSystemDimension(p1);
		PointF p2OnSys = getPointOnSystemDimension(p2);
		drawParabolReal(p1OnSys, p2OnSys);
	}

	public PointF getRealPoint(PointF p) {
		float panX = mSpenSurfaceView.getPan().x;
		float panY = mSpenSurfaceView.getPan().y;
		float zoom = mSpenSurfaceView.getZoomRatio();

		PointF result = new PointF();
		result.set(p.x / zoom + panX, p.y / zoom + panY);
		return result;
	}

	public RectF getRealPoint(float x, float y, float width, float height) {
		float panX = mSpenSurfaceView.getPan().x;
		float panY = mSpenSurfaceView.getPan().y;
		float zoom = mSpenSurfaceView.getZoomRatio();
		width *= zoom;
		height *= zoom;
		RectF realRect = new RectF();
		realRect.set((x - width / 2) / zoom + panX, (y - height / 2) / zoom
				+ panY, (x + width / 2) / zoom + panX, (y + height / 2) / zoom
				+ panY);
		return realRect;
	}

	public PointF[] getPointLine(PointF p1, PointF p2) {

		int pointSize = (int) Math.abs(p1.x - p2.x) + 2;
		if (p1.x == p2.x)
			pointSize = (int) Math.abs(p2.y - p1.y) + 2;

		PointF[] points = new PointF[pointSize];

		if (p1.x != p2.x) {
			int delta = 1;
			if (p1.x > p2.x)
				delta = -1;
			float x0 = p1.x - delta;
			for (int i = 0; i < pointSize; i++) {
				points[i] = new PointF();
				x0 = x0 + delta;
				points[i].x = x0;
				points[i].y = (x0 - p1.x) * (p2.y - p1.y) / (p2.x - p1.x)
						+ p1.y;
			}
			return points;
		} else {
			int delta = 1;
			if (p1.y > p2.y)
				delta = -1;
			float y0 = p1.y - delta;
			for (int i = 0; i < pointSize; i++) {
				points[i] = new PointF();
				y0 = y0 + delta;
				points[i].x = p1.x;
				points[i].y = y0;
			}
			return points;
		}
	}

	public String updateChange(RectF rect, String text) {
		String change = null;
		float left = rect.left;
		float right = rect.right;
		float top = rect.top;
		float bottom = rect.bottom;
		HashMap<Integer, PointF> twoPoint = AnalysisPoint.parsePoint(text);
		PointF startPoint = twoPoint.get(1);
		PointF endPoint = twoPoint.get(2);
		switch (Integer.parseInt(text.trim().substring(0,
				text.trim().indexOf(":")))) {
		case FinalValues.LINE:
			if (top < bottom) {
				if (startPoint.x == endPoint.x) {
					change = FinalValues.LINE + ":" + left + ";" + top + ";"
							+ left + ";" + bottom;
					Log.e("Line", "tan = vo cung");
				}
				if (startPoint.y == endPoint.y) {
					change = FinalValues.LINE + ":" + left + ";" + top + ";"
							+ right + ";" + top;
					Log.e("Line", "tan = 0");
				}
				if ((startPoint.y - endPoint.y) / (startPoint.x - endPoint.x) > 0) {
					change = FinalValues.LINE + ":" + left + ";" + top + ";"
							+ right + ";" + bottom;
					Log.e("Line", "tan > 0");
				} else if ((startPoint.y - endPoint.y)
						/ (startPoint.x - endPoint.x) < 0) {
					change = FinalValues.LINE + ":" + right + ";" + top + ";"
							+ left + ";" + bottom;
					Log.e("Line", "tan < 0");
				}
			} else {
				if (startPoint.x == endPoint.x) {
					change = FinalValues.LINE + ":" + left + ";" + top + ";"
							+ left + ";" + bottom;
					Log.e("Line", "tan = vo cung");
				}
				if (startPoint.y == endPoint.y) {
					change = FinalValues.LINE + ":" + left + ";" + bottom + ";"
							+ right + ";" + bottom;
					Log.e("Line", "tan = 0");
				}
				if ((startPoint.y - endPoint.y) / (startPoint.x - endPoint.x) > 0) {
					change = FinalValues.LINE + ":" + left + ";" + top + ";"
							+ right + ";" + bottom;
					Log.e("Line", "tan > 0");
				} else if ((startPoint.y - endPoint.y)
						/ (startPoint.x - endPoint.x) < 0) {
					change = FinalValues.LINE + ":" + right + ";" + top + ";"
							+ left + ";" + bottom;
					Log.e("Line", "tan < 0");
				}
			}
			break;
		case FinalValues.RECTANGLE:
			change = FinalValues.RECTANGLE + ":" + left + ";" + top + ";"
					+ right + ";" + bottom;
			break;
		case FinalValues.CIRCLE:
			float rl = right - left;
			float bt = bottom - top;
			PointF p1 = new PointF((float) (left + right) / 2,
					(float) (top + bottom) / 2);
			if (rl == bt) {
				change = FinalValues.CIRCLE + ":" + p1.x + ";" + p1.y + ";"
						+ right + ";" + top;
			} else {
				change = FinalValues.ELIP + ":" + p1.x + ";" + p1.y + ";"
						+ right + ";" + top;
			}
			break;
		case FinalValues.ELIP:
			float rle = right - left;
			float bte = bottom - top;
			PointF p1e = new PointF((float) (left + right) / 2,
					(float) (top + bottom) / 2);
			if (rle == bte) {
				change = FinalValues.CIRCLE + ":" + p1e.x + ";" + p1e.y + ";"
						+ right + ";" + top;
			} else {
				change = FinalValues.ELIP + ":" + p1e.x + ";" + p1e.y + ";"
						+ right + ";" + top;
			}
			break;
		case FinalValues.PARABOL:
			if (startPoint.y > endPoint.y) {
				change = FinalValues.PARABOL + ":" + (float) (left + right) / 2
						+ ";" + bottom + ";" + right + ";" + top;
			}
			if (startPoint.y < endPoint.y) {
				change = FinalValues.PARABOL + ":" + (float) (left + right) / 2
						+ ";" + top + ";" + right + ";" + bottom;
			}
			break;
		case FinalValues.NORMAL_TRIANGLE:
			break;
		case FinalValues.RIGHTSTRIANGLE:
			if (startPoint.x < endPoint.x && startPoint.y < endPoint.y) {
				change = FinalValues.RIGHTSTRIANGLE + ":" + left + ";" + top
						+ ";" + right + ";" + bottom;
			}
			if (startPoint.x > endPoint.x && startPoint.y < endPoint.y) {
				change = FinalValues.RIGHTSTRIANGLE + ":" + right + ";" + top
						+ ";" + left + ";" + bottom;
			}
			if (startPoint.x < endPoint.x && startPoint.y > endPoint.y) {
				change = FinalValues.RIGHTSTRIANGLE + ":" + left + ";" + bottom
						+ ";" + right + ";" + top;
			}
			if (startPoint.x > endPoint.x && startPoint.y > endPoint.y) {
				change = FinalValues.RIGHTSTRIANGLE + ":" + right + ";"
						+ bottom + ";" + left + ";" + top;
			}
			break;
		case FinalValues.TRIANGLE:
			if (startPoint.y < endPoint.y) {
				change = FinalValues.TRIANGLE + ":" + (float) (left + right)
						/ 2 + ";" + top + ";" + left + ";" + bottom;
			}
			if (startPoint.y > endPoint.x) {
				change = FinalValues.TRIANGLE + ":" + (float) (left + right)
						/ 2 + ";" + top + ";" + left + ";" + top;
			}
			break;

		case FinalValues.PARALLEL:
			if ((startPoint.y - endPoint.y) / (startPoint.x - endPoint.x) > 0) {
				change = FinalValues.PARALLEL + ":" + left + ";" + top + ";"
						+ right + ";" + bottom;
			} else if ((startPoint.y - endPoint.y)
					/ (startPoint.x - endPoint.x) < 0) {
				change = FinalValues.PARALLEL + ":" + right + ";" + top + ";"
						+ left + ";" + bottom;
			}
			break;
		case FinalValues.RHOMBUS:
			change = FinalValues.RHOMBUS + ":" + (float) (left + right) / 2
					+ ";" + top + ";" + right + ";" + (float) (top + bottom)
					/ 2;
			break;

		case FinalValues.ISOSCELES_TRAPEZOID:
			if (startPoint.y < endPoint.y) {
				change = FinalValues.ISOSCELES_TRAPEZOID + ":"
						+ (float) (3 * left + right) / 4 + ";" + top + ";"
						+ right + ";" + bottom;
			}
			if (startPoint.y > endPoint.y) {
				change = FinalValues.ISOSCELES_TRAPEZOID + ":"
						+ (float) (3 * left + right) / 4 + ";" + bottom + ";"
						+ right + ";" + top;
			}
			break;
		case FinalValues.ISOSCELES_SQUARE:
			if (startPoint.x < endPoint.x && startPoint.y < endPoint.y) {
				change = FinalValues.ISOSCELES_SQUARE + ":" + left + ";" + top
						+ ";" + right + ";" + bottom;
			}
			if (startPoint.x > endPoint.x && startPoint.y < endPoint.y) {
				change = FinalValues.ISOSCELES_SQUARE + ":" + right + ";" + top
						+ ";" + left + ";" + bottom;
			}
			if (startPoint.x < endPoint.x && startPoint.y > endPoint.y) {
				change = FinalValues.ISOSCELES_SQUARE + ":" + left + ";"
						+ bottom + ";" + right + ";" + top;
			}
			if (startPoint.x > endPoint.x && startPoint.y > endPoint.y) {
				change = FinalValues.ISOSCELES_SQUARE + ":" + right + ";"
						+ bottom + ";" + left + ";" + top;
			}
			break;
		}
		return change;
	}

	public PointF getPointOnSystemDimension(PointF point) {

		PointF result = new PointF();
		result.x = rootPoint.x + point.x * 40;
		result.y = rootPoint.y - point.y * 40;
		return result;
	}
}
